// FriendServiceImpl.java
package com.baoyouqun.API.friend;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baoyouqun.API.IM.TencentImService;
import com.baoyouqun.API.friend.domain.*;
import com.baoyouqun.base.PageResponse;
import com.baoyouqun.domain.VO.AddFriendDTO;
import com.baoyouqun.entity.User;
import com.baoyouqun.mapper.FriendRelationMapper;
import com.baoyouqun.service.SystemConfigService;
import com.baoyouqun.service.UserResourceService;
import com.baoyouqun.service.UserService;
import com.baoyouqun.service.UserVipTimeService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FriendServiceImpl extends ServiceImpl<FriendRelationMapper, FriendRelation> implements FriendService {

    @Resource
    private UserService userService;

    @Resource
    private UserResourceService userResourceService;

    @Resource
    private UserVipTimeService userVipTimeService;

    @Resource
    private TencentImService tencentImService;
    @Resource
    private SystemConfigService systemConfigService;

    @Override
    public SingleResponse<JSONObject> getFriend(String friendId) {
        String userId = StpUtil.getLoginIdAsString();

        // 获取好友关系
        FriendRelation relations = getOne(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, userId)
                        .eq(FriendRelation::getFriendId, friendId)
                        .last("limit 1")
        );
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("friendStatus", "-1");
        jsonObject.put("friendStatusName", "非好友");
        if (Objects.nonNull(relations)) {
            if (Objects.equals(relations.getStatus(), 0)) {
                jsonObject.put("friendStatus", "0");
                jsonObject.put("friendStatusName", "已申请待验证");

            } else if (Objects.equals(relations.getStatus(), 1)) {
                jsonObject.put("friendStatus", "1");
                jsonObject.put("friendStatusName", "已是好友");
            } else if (Objects.equals(relations.getStatus(), 2)) {
                jsonObject.put("friendStatus", "2");
                jsonObject.put("friendStatusName", "已拒绝");
            }
        }
        return SingleResponse.of(jsonObject);
    }

    @Override
    public MultiResponse<FriendVO> getFriendList() {
        String userId = StpUtil.getLoginIdAsString();

        // 获取好友关系
        List<FriendRelation> relations = list(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, userId)
                        .eq(FriendRelation::getStatus, 1) // 只获取已通过的好友
        );

        if (CollUtil.isEmpty(relations)) {
            return MultiResponse.of(Collections.emptyList());
        }

        // 获取好友ID列表
        List<String> friendIds = relations.stream()
                .map(FriendRelation::getFriendId)
                .collect(Collectors.toList());

        // 获取好友用户信息
        Map<String, User> userMap = userService.listByIds(friendIds).stream()
                .collect(Collectors.toMap(User::getId, user -> user));

        // 获取VIP状态
        Map<String, Boolean> vipStatusMap = userVipTimeService.getVipStatusByUserIds(friendIds);

        // 获取在线状态（从IM系统）

        Set<String> onlineStatusMap = tencentImService.getOnlineUserIds();

        // 获取用户资源和需求信息
        Map<String, List<String>> userResourcesMap = userResourceService.getUserResourcesMap(friendIds);
        Map<String, List<String>> userNeedsMap = userResourceService.getUserNeedsMap(friendIds);

        List<FriendVO> friends = new ArrayList<>();
        for (FriendRelation relation : relations) {
            User friend = userMap.get(relation.getFriendId());
            if (friend == null) continue;

            FriendVO friendVO = new FriendVO();
            friendVO.setId(friend.getId());
            friendVO.setName(StrUtil.isNotBlank(relation.getRemark()) ? relation.getRemark() : friend.getName());
            friendVO.setHeadImg(friend.getHeadImg());

            if (CollUtil.isEmpty(friend.getExtraPhones())) {
                friendVO.setContactMobile(friend.getCellphone());
            } else {
                friendVO.setContactMobile(friend.getExtraPhones().get(0));
            }

            friendVO.setIsVip(vipStatusMap.getOrDefault(friend.getId(), false));
            Boolean online = false;
            if (CollUtil.isNotEmpty(onlineStatusMap)) {
                online = onlineStatusMap.contains(friend.getId());
            }
            friendVO.setOnline(online);
            friendVO.setProvince(friend.getProvince());
            friendVO.setCity(friend.getCity());
            friendVO.setDistrict(friend.getDistrict());

            // 设置资源信息
            List<String> resources = userResourcesMap.getOrDefault(friend.getId(), Collections.emptyList());
            friendVO.setResourceCount(resources.size());
            friendVO.setTopResources(resources.stream().limit(3).collect(Collectors.toList()));

            // 设置需求信息
            List<String> needs = userNeedsMap.getOrDefault(friend.getId(), Collections.emptyList());
            friendVO.setNeedCount(needs.size());
            friendVO.setTopNeeds(needs.stream().limit(3).collect(Collectors.toList()));

            friendVO.setRemark(relation.getRemark());

            friends.add(friendVO);
        }

        return MultiResponse.of(friends);
    }


    @Override
    public MultiResponse<FriendVO> searchFriends(FriendSearchQuery query) {
        String userId = StpUtil.getLoginIdAsString();
        // 获取好友关系状态
        List<FriendRelation> relations = list(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getFriendId, userId)
                        .eq(FriendRelation::getStatus, 1)
        );

        if (CollUtil.isEmpty(relations)) {
            return MultiResponse.of(Collections.emptyList());
        }

        // 获取好友ID列表
        List<String> friendIds = relations.stream()
                .map(FriendRelation::getUserId)
                .collect(Collectors.toList());

        if (CollUtil.isEmpty(friendIds)) {
            return MultiResponse.of(Collections.emptyList());
        }
        // 搜索用户
        List<User> users = userService.list(
                new LambdaQueryWrapper<User>()
                        .like(StrUtil.isNotBlank(query.getKeyword()), User::getName, query.getKeyword())
                        .or()
                        .like(StrUtil.isNotBlank(query.getKeyword()), User::getCellphone, query.getKeyword())
                        .ne(User::getId, userId)// 排除自己
                        .in(User::getId, friendIds)
        );

        if (CollUtil.isEmpty(users)) {
            return MultiResponse.of(Collections.emptyList());
        }

        List<String> userIds = users.stream().map(User::getId).filter(friendIds::contains).collect(Collectors.toList());

        // 获取VIP状态
        Map<String, Boolean> vipStatusMap = userVipTimeService.getVipStatusByUserIds(userIds);

        // 获取在线状态
        Map<String, Boolean> onlineStatusMap = new HashMap<>();
//                tencentImService.getOnlineStatus(userIds);


        Map<String, Integer> relationStatusMap = relations.stream()
                .collect(Collectors.toMap(
                        FriendRelation::getUserId,
                        FriendRelation::getStatus,
                        (existing, newOne) -> existing
                ));
        List<FriendVO> result = new ArrayList<>();

        for (User user : users) {
            FriendVO friendVO = new FriendVO();
            friendVO.setId(user.getId());
            friendVO.setName(user.getName());
            friendVO.setHeadImg(user.getHeadImg());
            friendVO.setIsVip(vipStatusMap.getOrDefault(user.getId(), false));
            friendVO.setOnline(onlineStatusMap.getOrDefault(user.getId(), false));
            friendVO.setProvince(user.getProvince());
            friendVO.setCity(user.getCity());
            friendVO.setDistrict(user.getDistrict());

            // 设置关系状态
            Integer status = relationStatusMap.get(user.getId());
            if (status != null) {
                friendVO.setRemark(status == 0 ? "待验证" : status == 1 ? "已添加" : "已拒绝");
            } else {
                friendVO.setRemark("未添加");
            }

            result.add(friendVO);
        }

        return MultiResponse.of(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response addFriend(AddFriendCmd cmd) {
        String userId = StpUtil.getLoginIdAsString();

        // 不能添加自己为好友
        if (userId.equals(cmd.getFriendId())) {
            return Response.buildFailure("50001", "不能添加自己为好友");
        }

        AddFriendDTO addFriendDTO = systemConfigService.getAddFriend();
        if (addFriendDTO != null) {
            if (Objects.equals(addFriendDTO.getEnableLimit(), Boolean.TRUE)) {
                long todayAdd = count(new LambdaQueryWrapper<FriendRelation>().ge(FriendRelation::getCreateTime, LocalDate.now().atStartOfDay()));
                if (todayAdd > addFriendDTO.getDailyLimit()) {
                    return Response.buildFailure("50001", "已达到每日添加好友上限" + addFriendDTO.getDailyLimit());
                }
            }
        }


        // 检查是否已是好友
        FriendRelation existingRelation = getOne(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, userId)
                        .eq(FriendRelation::getFriendId, cmd.getFriendId())
        );

        if (existingRelation != null) {
            if (existingRelation.getStatus() == 1) {
                return Response.buildFailure("50002", "已是好友");
            } else if (existingRelation.getStatus() == 0) {
                return Response.buildFailure("50003", "已发送申请，等待验证");
            }
        }

        // 创建好友申请
        FriendRelation relation = new FriendRelation();
        relation.setUserId(userId);
        relation.setFriendId(cmd.getFriendId());
        relation.setRemark(cmd.getRemark());
        relation.setStatus(0); // 待验证
        relation.setCreateTime(LocalDateTime.now());

        if (save(relation)) {
            // 同步到IM系统
            tencentImService.addFriend(userId, cmd.getFriendId(), cmd.getRemark());
            return Response.buildSuccess();
        }

        return Response.buildFailure("50004", "添加好友失败");
    }

    @Override
    public MultiResponse<FriendApplicationVO> getFriendApplications() {
        String userId = StpUtil.getLoginIdAsString();

        // 获取待处理的好友申请
        List<FriendRelation> applications = list(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getFriendId, userId)
                        .eq(FriendRelation::getStatus, 0)
        );

        if (CollUtil.isEmpty(applications)) {
            return MultiResponse.of(Collections.emptyList());
        }

        // 获取申请人ID列表
        List<String> applicantIds = applications.stream()
                .map(FriendRelation::getUserId)
                .collect(Collectors.toList());

        // 获取申请人信息
        Map<String, User> userMap = userService.listByIds(applicantIds).stream()
                .collect(Collectors.toMap(User::getId, user -> user));

        // 转换为VO
        List<FriendApplicationVO> result = new ArrayList<>();
        for (FriendRelation application : applications) {
            User applicant = userMap.get(application.getUserId());
            if (applicant == null) continue;

            FriendApplicationVO vo = new FriendApplicationVO();
            vo.setId(application.getId());
            vo.setApplicantId(applicant.getId());
            vo.setApplicantName(applicant.getName());
            vo.setApplicantHeadImg(applicant.getHeadImg());
            vo.setApplicationRemark(application.getRemark());
            vo.setCreateTime(application.getCreateTime().toString());
            vo.setStatus(application.getStatus());

            result.add(vo);
        }

        return MultiResponse.of(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response handleFriendApplication(HandleFriendApplicationCmd cmd) {
        String userId = StpUtil.getLoginIdAsString();

        // 获取申请信息
        FriendRelation application = getById(cmd.getApplicationId());
        if (application == null) {
            return Response.buildFailure("50005", "申请不存在");
        } else if (!userId.equals(application.getFriendId())) {
            return Response.buildFailure("50005", "申请无权处理");
        }

        // 更新申请状态
        application.setStatus(cmd.getStatus());
        application.setUpdateTime(LocalDateTime.now());
        updateById(application);

        // 如果是通过申请，创建反向关系
        if (cmd.getStatus() == 1) {
            FriendRelation reverseRelation = new FriendRelation();
            reverseRelation.setUserId(userId);
            reverseRelation.setFriendId(application.getUserId());
            reverseRelation.setStatus(1); // 已通过
            reverseRelation.setCreateTime(LocalDateTime.now());
            save(reverseRelation);
        }

        return Response.buildSuccess();
    }

    @Override
    public Response updateFriendRemark(UpdateFriendRemarkCmd cmd) {
        String userId = StpUtil.getLoginIdAsString();

        // 检查好友关系是否存在
        FriendRelation relation = getOne(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, userId)
                        .eq(FriendRelation::getFriendId, cmd.getFriendId())
                        .eq(FriendRelation::getStatus, 1)
        );

        if (relation == null) {
            return Response.buildFailure("50006", "好友关系不存在");
        }

        // 更新备注
        relation.setRemark(cmd.getRemark());
        relation.setUpdateTime(LocalDateTime.now());
        updateById(relation);

        return Response.buildSuccess();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response deleteFriend(String friendId) {
        String userId = StpUtil.getLoginIdAsString();

        // 删除正向关系
        boolean delete1 = remove(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, userId)
                        .eq(FriendRelation::getFriendId, friendId)
        );

        // 删除反向关系
        boolean delete2 = remove(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, friendId)
                        .eq(FriendRelation::getFriendId, userId)
        );

        if (delete1 || delete2) {
            // 同步到IM系统
            tencentImService.deleteFriend(userId, friendId);
            return Response.buildSuccess();
        }

        return Response.buildFailure("50007", "删除好友失败");
    }

    @Override
    public PageResponse<PublicFriendVO> getPublicFriendList(PublicFriendQuery query) {
        String userId = StpUtil.getLoginIdAsString();

        // 构建分页查询条件
        Page<User> page = new Page<>(query.getPageIndex(), query.getPageSize());

        // 查询公开用户（假设User表中有isPublic字段标识是否为公开豹友）
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getIsPublic, true) // 1表示公开豹友
                .ne(User::getId, userId)   // 排除自己
                .eq(StrUtil.isNotBlank(query.getProvince()), User::getProvince, query.getProvince())
                .eq(StrUtil.isNotBlank(query.getCity()), User::getCity, query.getCity())
                .apply(Objects.nonNull(query.getLatitude()) && Objects.nonNull(query.getLongitude()),
                        "6371 * acos(cos(radians({0})) * cos(radians(latitude)) *  cos(radians(longitude) - radians({1})) + sin(radians({0})) * sin(radians(latitude))) < {2}",
                        query.getLatitude(), query.getLongitude(), 20);

        // 执行分页查询
        Page<User> userPage = userService.page(page, wrapper);

        // 转换为VO
        List<PublicFriendVO> voList = convertToPublicFriendVO(userPage.getRecords(), userId);

        return PageResponse.of(voList, (int) userPage.getTotal(), query.getPageIndex(), query.getPageSize());
    }

    @Override
    public SingleResponse<Integer> getNearbyFriendCount(NearbyFriendQuery query) {
        String userId = StpUtil.getLoginIdAsString();

        // 获取当前用户位置（假设User表中有latitude和longitude字段）
        User currentUser = userService.getById(userId);
        if (currentUser == null || currentUser.getLatitude() == null || currentUser.getLongitude() == null) {
            return SingleResponse.of(0);
        }

        // 查询附近的公开豹友（使用Haversine公式计算距离）
        List<User> nearbyUsers = userService.list(
                new LambdaQueryWrapper<User>()
                        .eq(User::getIsPublic, 1)
                        .ne(User::getId, userId)
                        .apply("6371 * acos(cos(radians({0})) * cos(radians(latitude)) * " +
                                        "cos(radians(longitude) - radians({1})) + sin(radians({0})) * sin(radians(latitude))) < {2}",
                                query.getLatitude(), query.getLongitude(), query.getRadius())
        );

        return SingleResponse.of(nearbyUsers.size());
    }

    @Override
    public PageResponse<PublicFriendVO> searchPublicFriends(PublicFriendQuery query) {
        String userId = StpUtil.getLoginIdAsString();

        // 构建分页查询条件
        Page<User> page = new Page<>(query.getPageIndex(), query.getPageSize());

        // 搜索公开豹友
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getIsPublic, 1)
                .ne(User::getId, userId)
                .and(StrUtil.isNotBlank(query.getKeyword()), w -> w
                        .like(User::getName, query.getKeyword())
                        .or()
                );

        // 执行分页查询
        Page<User> userPage = userService.page(page, wrapper);

        // 转换为VO
        List<PublicFriendVO> voList = convertToPublicFriendVO(userPage.getRecords(), userId);

        return PageResponse.of(voList, (int) userPage.getTotal(), query.getPageIndex(), query.getPageSize());
    }

    // 辅助方法：将User列表转换为PublicFriendVO列表
    private List<PublicFriendVO> convertToPublicFriendVO(List<User> users, String currentUserId) {
        if (CollUtil.isEmpty(users)) {
            return Collections.emptyList();
        }

        List<String> userIds = users.stream()
                .map(User::getId)
                .collect(Collectors.toList());

        // 获取VIP状态
        Map<String, Boolean> vipStatusMap = userVipTimeService.getVipStatusByUserIds(userIds);

        // 获取在线状态
        Map<String, String> onlineStatusMap = tencentImService.getOnlineStatus(userIds);

        // 获取好友关系状态
        List<FriendRelation> relations = list(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, currentUserId)
                        .in(FriendRelation::getFriendId, userIds)
        );

        Map<String, Integer> relationStatusMap = relations.stream()
                .collect(Collectors.toMap(
                        FriendRelation::getFriendId,
                        FriendRelation::getStatus,
                        (existing, newOne) -> existing
                ));

        // 转换为VO
        List<PublicFriendVO> result = new ArrayList<>();
        for (User user : users) {
            PublicFriendVO vo = new PublicFriendVO();
            vo.setId(user.getId());
            vo.setName(user.getName());
            vo.setHeadImg(user.getHeadImg());
            vo.setIsVip(vipStatusMap.getOrDefault(user.getId(), false));

            String online = onlineStatusMap.getOrDefault(user.getId(), "false");
            vo.setOnline("online".equals(online));
            vo.setProvince(user.getProvince());
            vo.setCity(user.getCity());
            vo.setDistrict(user.getDistrict());
            vo.setLatitude(user.getLatitude());
            vo.setLongitude(user.getLongitude());

            // 设置关系状态
            Integer status = relationStatusMap.get(user.getId());
            if (status != null) {
                vo.setRelationStatus(status == 0 ? "待验证" : status == 1 ? "已添加" : "已拒绝");
            } else {
                vo.setRelationStatus("未添加");
            }

            result.add(vo);
        }

        return result;
    }
}